home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dutil / save / fdtopragma.c < prev    next >
C/C++ Source or Header  |  1994-01-30  |  9KB  |  436 lines

  1.  
  2. /*
  3.  *  FDTOPRAGMA.C
  4.  *
  5.  * (c)Copyright 1992 Obvious Implementations Corp, All Rights Reserved
  6.  *
  7.  *  FDTOPRAGMA fdfile [-o inline_header_file]
  8.  *  FDTOPRAGMA fddir  [-o inlinedir]
  9.  *
  10.  *  Generates an #include file for inline library calls given an FD file
  11.  *  and CLIB-style prototype file.  The generated header file consists of
  12.  *  entries as follows:
  13.  *
  14.  *  void func1(__A6 void *,__D0 int, __D1 int);
  15.  *  #pragma FubarBase func1 2e 0102
  16.  *  ...
  17.  */
  18.  
  19. #ifndef unix
  20. #include <exec/types.h>
  21. #include <exec/nodes.h>
  22. #include <exec/lists.h>
  23. #include <clib/alib_protos.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/dos_protos.h>
  26. #include <clib/alib_protos.h>
  27. #include <lib/profile.h>
  28. #include <lib/version.h>
  29. #include <lists.h>
  30. #include <time.h>
  31. #else
  32. #include <../suplib/all.h>
  33. #endif
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <stdarg.h>
  38. #include <sys/stat.h>
  39. #include <sys/dir.h>
  40.  
  41.  
  42. #ifdef _DCC
  43. IDENT("fdtopragma", ".9");
  44. DCOPYRIGHT;
  45. #endif
  46.  
  47. typedef unsigned char  ubyte;
  48. typedef unsigned short uword;
  49. typedef unsigned long  ulong;
  50. typedef struct List    List;
  51. typedef struct Node    Node;
  52.  
  53. typedef struct FDNode {
  54.     Node    fn_Node;
  55.     short   fn_Args;
  56.     long    fn_Offset;        /*    library offset        */
  57.     char    fn_Regs[32];    /*    transfer registers  */
  58. } FDNode;
  59.  
  60. void    help(short);
  61. void    exiterr(const char *, ...);
  62. void    ScanFD(FILE *);
  63. char    *ParseArg(char *, char **);
  64. void    GenerateOutput(FILE *, char *);
  65. void    GenerateFunction(char *, long);
  66. void    GeneratePragmas(char *, char *);
  67.  
  68. List    FDList;     /*  list of FD files   */
  69.  
  70. char    *BaseVar;
  71. char    *BaseVarPtr;
  72.  
  73. char    Buf[256];
  74.  
  75. int _DiceCacheEnable = 1;
  76.  
  77. main(ac, av)
  78. short ac;
  79. char **av;
  80. {
  81.     short i;
  82.     struct stat s;
  83.     char *fdName = NULL;
  84.     char *outName = NULL;
  85.  
  86.     for (i = 1; i < ac; ++i) {
  87.     char *ptr = av[i];
  88.  
  89.     if (*ptr != '-') {
  90.         if (fdName == NULL)fdName = ptr;
  91.         else help(1);
  92.         continue;
  93.     }
  94.     ptr += 2;
  95.     switch(ptr[-1]) {
  96.     case 'o':
  97.         outName = (*ptr) ? ptr : av[++i];
  98.         break;
  99.     default:
  100.         help(0);
  101.         break;
  102.     }
  103.     }
  104.     if (fdName == NULL)
  105.     help(0);
  106.  
  107.     /*
  108.      *    HACK, handle case where fdName is a directory
  109.      */
  110.     if (stat(fdName, &s) == 0 && (s.st_mode & S_IFDIR)) {
  111.     DIR *dir;
  112.     struct direct *direct;
  113.  
  114.     if (dir = opendir(fdName)) {
  115.         while (direct = readdir(dir)) {
  116.         char *ptr;
  117.  
  118.         if (ptr = strstr(direct->d_name, "_lib.fd")) {
  119.             static char FdPath[256];
  120.             static char OutPath[256];
  121.  
  122.             sprintf(FdPath, "%s%s", fdName, direct->d_name);
  123.             sprintf(OutPath, "%s%.*s_pragmas.h", outName ? outName : "",
  124.                              ptr - direct->d_name, direct->d_name);
  125.             GeneratePragmas(FdPath, OutPath);
  126.         } else {
  127.             fprintf(stderr, "%s: expected '_lib.fd' trailer\n");
  128.         }
  129.         }
  130.         closedir(dir);
  131.     }
  132.     }
  133.     else {
  134.     GeneratePragmas(fdName, outName);
  135.     }
  136.     return(0);
  137. }
  138.  
  139. void
  140. GeneratePragmas(fdFile, outFile)
  141. char *fdFile;
  142. char *outFile;
  143. {
  144.     NewList(&FDList);
  145.     BaseVarPtr = BaseVar = NULL;
  146.  
  147.     if(outFile)printf("FD=%s OUT=%s\n", fdFile, outFile);
  148.     else printf("FD=%s\n", fdFile);
  149.  
  150.     /*
  151.      *    Generate FD specifications from FD file
  152.      */
  153.  
  154.     {
  155.     FILE *fi;
  156.     if ((fi = fopen(fdFile, "r")) == NULL)
  157.         exiterr("Unable to open .FD file: %s", fdFile);
  158.     ScanFD(fi);
  159.     fclose(fi);
  160.     }
  161.  
  162.     /*
  163.      *    Generate output
  164.      */
  165.  
  166.     if (outFile) {
  167.     FILE *fo;
  168.  
  169.     if (fo = fopen(outFile, "w")) {
  170.         GenerateOutput(fo, outFile);
  171.         fclose(fo);
  172.     } else {
  173.         exiterr("Can't create %s\n", outFile);
  174.     }
  175.     } else {
  176.     GenerateOutput(stdout, outFile);
  177.     }
  178. }
  179.  
  180. void
  181. exiterr(const char *ctl, ...)
  182. {
  183.     va_list va;
  184.  
  185.     va_start(va, ctl);
  186.     vfprintf(stderr, ctl, va);
  187.     va_end(va);
  188.     fprintf(stderr, "\n");
  189.     exit(5);
  190. }
  191.  
  192. void
  193. help(short code)
  194. {
  195. #ifdef _DCC
  196.     puts(Ident);
  197. #endif
  198.     puts("FDTOPRAGMA fdfile [-o outfile]");
  199.     puts("FDTOPRAGMA fddir/ [-o outdir/]");
  200.     puts("  Generates header files for inline library calls");
  201.     exit(code);
  202. }
  203.  
  204. void
  205. ScanFD(fi)
  206. FILE *fi;
  207. {
  208.     long bias = -1;
  209.     short end = 0;
  210.     short public = 1;
  211.  
  212.     char *key;
  213.  
  214.     while (fgets(Buf, sizeof(Buf), fi)) {
  215.     if (Buf[0] == '\n' || Buf[0] == '*')
  216.         continue;
  217.     if (strncmp(Buf, "##", 2) != 0) {
  218.         if (bias < 0 || BaseVar == NULL) {
  219.         if (bias < 0) {
  220.             bias = 30;
  221.             printf("Error, No ##bias before function: %s\n", Buf);
  222.         }
  223.         if (BaseVar == NULL) {
  224.             BaseVarPtr = BaseVar = strdup("UnknownBase");
  225.             printf("Error, No ##base before function: %s\n", Buf);
  226.         }
  227.         }
  228.         if (public)
  229.         GenerateFunction(Buf, bias);
  230.         bias += 6;
  231.         continue;
  232.     }
  233.     if ((key = strtok(Buf + 2, " \t\n")) == NULL) {
  234.         printf("\tError, Illegal null directive\n");
  235.         continue;
  236.     }
  237.     if (stricmp(key, "base") == 0) {
  238.         if (key = strtok(NULL, " \t\n")) {
  239.         if (BaseVar)
  240.             free(BaseVar);
  241.         BaseVarPtr = BaseVar = strdup(key);
  242.         if (BaseVar[0] == '_')
  243.             ++BaseVarPtr;
  244.         } else {
  245.         printf("\tError, Illegal ##base directive\n");
  246.         }
  247.         continue;
  248.     }
  249.     if (stricmp(key, "bias") == 0) {
  250.         if (key = strtok(NULL, " \t\n")) {
  251.         char *dummy;
  252.  
  253.         bias = strtol(key, &dummy, 0);
  254.         if (bias <= 0)
  255.             printf("\tError, Illegal ##bias: %d\n", bias);
  256.         } else {
  257.         printf("\tError, Illegal ##bias directive\n");
  258.         }
  259.         continue;
  260.     }
  261.     if (stricmp(key, "public") == 0) {
  262.         public = 1;
  263.         continue;
  264.     }
  265.     if (stricmp(key, "private") == 0) {
  266.         public = 0;
  267.         continue;
  268.     }
  269.     if (stricmp(key, "end") == 0) {
  270.         end = 1;
  271.         break;
  272.     }
  273.     printf("\tError, Unrecognized directive: %s\n", key);
  274.     }
  275.     if (bias < 0)
  276.     puts("\tUnexpected EOF, no ##bias");
  277.     if (BaseVar == NULL)
  278.     puts("\tUnexpected EOF, no ##base");
  279.     if (end == 0)
  280.     puts("\tUnexpected EOF, no ##end directive");
  281. }
  282.  
  283. /*
  284.  *  funcname(var,var,var)(reg,reg,reg)        (or reg/reg)
  285.  */
  286.  
  287. void
  288. GenerateFunction(buf, bias)
  289. char *buf;
  290. long bias;
  291. {
  292.     FDNode *fd = malloc(sizeof(FDNode));
  293.     char *scanPtr = buf;
  294.  
  295.     clrmem(fd, sizeof(FDNode));
  296.  
  297.     fd->fn_Offset = bias;
  298.  
  299.     {
  300.     short noArgs = 0;
  301.  
  302.     while (*scanPtr && *scanPtr != '\t' && *scanPtr != ' ' && *scanPtr != '(')
  303.         ++scanPtr;
  304.     if (*scanPtr == ' ' || *scanPtr == '\t') {
  305.         while (*scanPtr && *scanPtr != '(')
  306.         *scanPtr++ = 0;
  307.     }
  308.     if (*scanPtr == '(') {
  309.         *scanPtr++ = 0;
  310.         if (*scanPtr == ')')
  311.         noArgs = 1;
  312.     }
  313.     while (*scanPtr && *scanPtr != ')')   /*  skip text args  */
  314.         ++scanPtr;
  315.     while (*scanPtr && *scanPtr != '(')
  316.         ++scanPtr;
  317.     if (noArgs == 0 && *scanPtr == 0) {
  318.         printf("\tError in line: %s\n", buf);
  319.         return;
  320.     }
  321.     }
  322.     fd->fn_Node.ln_Name = strdup(buf);
  323.  
  324.     /*
  325.      *    get register description
  326.      */
  327.  
  328.     if (*scanPtr)
  329.     ++scanPtr;
  330.  
  331.     for (fd->fn_Args = 0; *scanPtr && *scanPtr != '\n' && *scanPtr != ')'; ++fd->fn_Args) {
  332.     switch(*scanPtr) {
  333.     case 'd':
  334.     case 'D':
  335.         fd->fn_Regs[fd->fn_Args] = *++scanPtr - '0';
  336.         ++scanPtr;
  337.         break;
  338.     case 'a':
  339.     case 'A':
  340.         fd->fn_Regs[fd->fn_Args] = *++scanPtr - '0' + 8;
  341.         ++scanPtr;
  342.         break;
  343.     default:
  344.         printf("\tError in register spec: %s\n", scanPtr);
  345.         return;
  346.     }
  347.     if (*scanPtr == ',' || *scanPtr == '/')
  348.         ++scanPtr;
  349.     }
  350.     if (fd->fn_Args == 0 && *scanPtr != ')') {
  351.     printf("\tError in register spec: %s\n", scanPtr);
  352.     return;
  353.     }
  354.     AddTail(&FDList, &fd->fn_Node);
  355. }
  356.  
  357.  
  358. char *
  359. ParseArg(ptr, ppt)
  360. char *ptr;
  361. char **ppt;
  362. {
  363.     char *base = ptr;
  364.  
  365.     if (ptr) {
  366.     while (*ptr && *ptr != '(')
  367.         ++ptr;
  368.     if (*ptr == '(') {
  369.         for (base = ++ptr; *ptr && *ptr != ')'; ++ptr)
  370.         ;
  371.         if (*ptr == ')') {
  372.         *ptr++ = 0;
  373.         *ppt = strdup(base);
  374.         } else {
  375.         ptr = NULL;
  376.         }
  377.     } else {
  378.         ptr = NULL;
  379.     }
  380.     }
  381.     return(ptr);
  382. }
  383.  
  384. void
  385. GenerateOutput(fo, outFile)
  386. FILE *fo;
  387. char *outFile;
  388. {
  389.     FDNode *fd;
  390.  
  391.     /* ** $ VER: proto/diskfont.h 1.0 (17.4.93) **        */
  392.     /* #ifndef DISKFONT_PROTO_H                          */
  393.     /* #define DISKFONT_PROTO_H 1                        */
  394.     /* #include <pragmas/config.h>                       */
  395.     /* #include <exec/types.h>                           */
  396.     /* #include <clib/diskfont_protos.h>                 */
  397.     /* #ifdef __SUPPORTS_PRAGMAS__                       */
  398.     /* extern struct Library *DiskfontBase;              */
  399.     /* #include <pragmas/diskfont_pragmas.h>             */
  400.     /* #endif                                            */
  401.     /* #endif                                            */
  402.  
  403.     {
  404.     time_t t;
  405.     struct tm *tp;
  406.  
  407.     time(&t);
  408.     tp = localtime(&t);
  409.  
  410.     fprintf(fo, "/* %cVER: %s 1.0 (%d.%d.%d) */\n",
  411.                '$',outFile ? outFile : "",
  412.                tp->tm_mday, tp->tm_mon, tp->tm_year);
  413.     }
  414.  
  415.     fprintf(fo, "#ifndef %s_PRAGMA_H\n", BaseVarPtr);
  416.     fprintf(fo, "#define %s_PRAGMA_H\n\n", BaseVarPtr);
  417.  
  418.     /*
  419.      *    #define's to generate library calls
  420.      */
  421.  
  422.     for (fd = GetHead(&FDList); fd; fd = GetSucc(&fd->fn_Node))
  423.     {
  424.     short i;
  425.  
  426.     fprintf(fo, "#pragma libcall %s %s %lx ", BaseVarPtr,
  427.                 fd->fn_Node.ln_Name, fd->fn_Offset);
  428.  
  429.     for (i = fd->fn_Args - 1; i >= 0; --i)
  430.         fprintf(fo, "%x", fd->fn_Regs[i]);
  431.     fprintf(fo, "0%x\n", fd->fn_Args & 15);
  432.     }
  433.     fprintf(fo, "\n#endif\n");
  434. }
  435.  
  436.